package com.sxt.netty;

//import java.net.InetSocketAddress;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @模块目的/功能：Netty服务器端
 * @版权说明：
 * @版本号：1.0
 * @日期：2019.11.13
 * @作者：罗林
 */
public class NettyServer {
	
    private EventLoopGroup bossGroup = null;
    //
    private EventLoopGroup workerGroup = null;
    
	 /**
     * @函数的名称:NettyServer
     * @目的/功能:无参构造函数
     * @输入参数:无
     * @返回值:无
     * @作者:罗林 
     * @日期:2019.11.13
     */
    public NettyServer() {
    	
    }
       

    /**
    * @函数的名称:startServer
    * @目的/功能:启动服务器
    * @输入参数:无
    * @返回值:
    * @作者:罗林 
    * @日期:2019.11.13
    */
   //public  void startServer(InetSocketAddress socketAddress) {
    public synchronized void startServer(Integer port) {
	   /**针对linux优化*/
       String osName = System.getProperty("os.name");
       /**配置服务端的NIO线程组*/
       if (osName.equalsIgnoreCase("Linux")) {
           /**负责服务端接收客户端的连接*/
           this.bossGroup = new EpollEventLoopGroup();
           /**负责进行SocketChannel的网络读写*/
           this.workerGroup = new EpollEventLoopGroup();
       } else {
           /**负责服务端接收客户端的连接*/
           this.bossGroup = new NioEventLoopGroup();
           /**负责进行SocketChannel的网络读写*/
           this.workerGroup = new NioEventLoopGroup();
       }
       /**Netty启动Nio服务端的辅助类*/
       ServerBootstrap bootstrap = new ServerBootstrap();
       
       bootstrap.group(this.bossGroup, this.workerGroup)
               //keepAlive默认是打开
               .option(ChannelOption.SO_KEEPALIVE, true)//保持连接
               .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
               .option(ChannelOption.SO_SNDBUF, 1024 * 256) //发包缓冲区，单位多少？
               .option(ChannelOption.SO_RCVBUF, 1024 * 256) //收包缓冲区，单位多少？
               .option(ChannelOption.TCP_NODELAY, true); //TCP立即发包
       /**Linux平台用Epoll模式**/
       if (osName.equals("Linux")) { //Linux平台用Epoll模式
           bootstrap.channel(EpollServerSocketChannel.class);
       } else {
           bootstrap.channel(NioServerSocketChannel.class);
       }
       
       /**添加解码器、编码器*/
       bootstrap.childHandler(new MsgCoderHandler());

       try {
			/**绑定端口同步操作*/
			ChannelFuture future = bootstrap.bind(port).sync();
			/** 4、监听端口关闭(//等待客户端链路关闭)**/
			future.channel().closeFuture().sync();
       	} catch (Exception e) {
       		e.printStackTrace();
       	} finally {
			/**优雅退出,释放资源*/
	        //关闭工作线程组
			this.workerGroup.shutdownGracefully();
	        //关闭主线程组
			this.bossGroup.shutdownGracefully();
       	}
   }
}
